<template>
  <div>
    <div class="containers" :style="{ display: 'flex', width: '100%', height: height }">
      <div style="width: 100%" id="canvas"></div>
      <div id="properties"></div>
    </div>
    <div v-if="!viewOnly && !readOnly" style="text-align: center">
      <el-button type="info" @click="clear">清空</el-button>
      <el-button type="success" @click="save">保存</el-button>
    </div>
  </div>
</template>
<script>
import BpmnModeler from 'camunda-bpmn-js/lib/camunda-platform/Modeler'
import BpmnViewer from 'camunda-bpmn-js/lib/camunda-platform/Viewer'
import { customTranslate } from './lang/zh/translations'
import 'camunda-bpmn-js/dist/assets/camunda-platform-modeler.css'
import './CamundaBpmn.less'

export default {
  name: 'camundaBpmn',
  props: {
    modelValue: {
      type: String,
      default: ''
    },
    format: {
      type: Boolean,
      default: false
    },
    preamble: {
      type: Boolean,
      default: true
    },
    readOnly: {
      type: Boolean,
      default: false
    },
    viewOnly: {
      type: Boolean,
      default: false
    },
    /**
     * {
     *   highlightNodeList: [
     *     { id: 'StartEvent_1', complete: true },
     *     { id: 'test1', complete: false }
     *   ],
     *   highlightLineList: [{ id: 'Flow_17z758r' }]
     * }
     */
    highlightElement: {
      type: Object,
      default: function () {
        return {
          highlightNodeList: [],
          highlightLineList: []
        }
      }
    },
    height: {
      type: String,
      default: '78vh'
    }
  },
  data() {
    return {
      bpmnModeler: undefined
    }
  },
  methods: {
    doInitBpmn() {
      if (this.bpmnModeler) {
        this.bpmnModeler.destroy()
        this.bpmnModeler.detach()
      }
      if (this.viewOnly) {
        this.bpmnModeler = new BpmnViewer({ container: '#canvas' })
      } else {
        this.bpmnModeler = new BpmnModeler({
          container: '#canvas',
          propertiesPanel: {
            parent: '#properties'
          },
          additionalModules: [
            {
              translate: ['value', customTranslate]
            }
          ]
        })
      }
      const logo = document.querySelector('.bjs-powered-by')
      while (logo.firstChild) {
        logo.removeChild(logo.firstChild)
      }
      if (this.modelValue && this.modelValue !== '') {
        this.bpmnModeler
          .importXML(this.modelValue)
          .then((result) => {
            if (result.warnings.length > 0) {
              console.warn(result.warnings)
            }
            const canvas = this.bpmnModeler.get('canvas')
            canvas.zoom('fit-viewport', 'auto')
            if (this.viewOnly) {
              this.highlightView(canvas)
            }
          })
          .catch((error) => {
            console.error('could not import BPMN 2.0 diagram', error)
          })
      } else {
        this.bpmnModeler.createDiagram()
      }
    },
    highlightView(canvas) {
      const highlightNodeList = this.highlightElement.highlightNodeList || []
      const highlightLineList = this.highlightElement.highlightLineList || []
      highlightNodeList.forEach((node) => {
        if (node.complete) {
          canvas.addMarker(node, 'highlightNode')
        } else {
          canvas.addMarker(node, 'highlightNodeCurrent')
        }
      })
      highlightLineList.forEach((line) => {
        canvas.addMarker(line, 'highlightLine')
      })
    },
    clear() {
      if (this.bpmnModeler) {
        this.bpmnModeler.clear()
      }
    },
    save() {
      this.bpmnModeler
        .saveXML({ format: this.format, preamble: this.preamble })
        .then((result) => {
          if (!result.error) {
            this.$emit('save', result.xml)
          } else {
            console.log(result.error)
          }
        })
        .catch((e) => {
          console.log(e)
        })
    }
  }
}
</script>
